﻿Imports System.Web.Services.Protocols
Imports System.Net.Mail
Imports System.Configuration
Imports System.IO

Public Class LogHelper

    Public Enum LogType
        Information
        Warning
        Exception
    End Enum

    Public Shared Sub Log(ByVal Message As String, ByVal Ex As Exception, ByVal Type As LogType)

        Dim objEvent As New EventLog
        Dim strLog As String
        Dim objSmtp As SmtpClient
        Dim objMail As MailMessage
        Dim strNotify As String
        Dim strSubject As String

        strLog = Message

        If Ex IsNot Nothing Then
            If TypeOf Ex Is SoapException Then
                strLog &= vbCrLf & vbCrLf & "Exception: " & vbCrLf & Ex.Message
                strLog &= vbCrLf & vbCrLf & "Details: " & vbCrLf & CType(Ex, SoapException).Detail.InnerText
            Else
                strLog &= vbCrLf & vbCrLf & "Exception: " & vbCrLf & Ex.Message

                If Ex.InnerException IsNot Nothing Then
                    strLog &= vbCrLf & vbCrLf & "InnerException: " & vbCrLf & Ex.InnerException.Message
                End If
            End If
            strLog &= vbCrLf & vbCrLf & "Stack trace: " & vbCrLf & Ex.StackTrace
        End If

        'Create the event log source
        If ConfigurationManager.AppSettings("logeventlog") = "true" Then

            If Not System.Diagnostics.EventLog.SourceExists("CRMQueueManager") Then
                Try
                    System.Diagnostics.EventLog.CreateEventSource("CRMQueueManager", "Application")
                Catch ex1 As Exception
                    'How to report now? Simply disable it.
                End Try
            End If

            Try
                objEvent.Source = "CRMQueueManager"
                objEvent.Log = "Application"

                Select Case Type
                    Case LogType.Exception
                        objEvent.WriteEntry(strLog, EventLogEntryType.Error)
                    Case LogType.Information
                        objEvent.WriteEntry(strLog, EventLogEntryType.Information)
                    Case LogType.Warning
                        objEvent.WriteEntry(strLog, EventLogEntryType.Warning)

                End Select
            Catch ex1 As Exception
                'This can fail, simply ignore it
            End Try
        End If

        If Type = LogType.Exception Then
            If ConfigurationManager.AppSettings("logerrornotify") <> "" Then
                strNotify = ConfigurationManager.AppSettings("logerrornotify")
                strSubject = "CRM Queue Manager Error"
            End If
        ElseIf Type = LogType.Warning Then
            If ConfigurationManager.AppSettings("logwarningnotify") <> "" Then
                strNotify = ConfigurationManager.AppSettings("logwarningnotify")
                strSubject = "CRM Queue Manager Warning"
            End If
        End If

        'Log to console
        Output(strLog, True, True)

        If strNotify <> "" Then
            objMail = New MailMessage(ConfigurationManager.AppSettings("lognotifyfrom"), strNotify)
            objSmtp = New SmtpClient

            objMail.Subject = strSubject
            objMail.IsBodyHtml = False
            objMail.Body = strLog

            Try
                'Workaround for Google
                If objSmtp.Host.Contains("gmail") Then
                    objSmtp.EnableSsl = True
                End If

                objSmtp.Send(objMail)
            Catch ex1 As Exception
                Try
                    objEvent.WriteEntry("Exception while sending error notification mail: " & Ex.Message, EventLogEntryType.Error)
                Catch ex2 As Exception
                    'Nothing more we can do 
                End Try
            End Try
        End If

    End Sub

    Public Shared Sub Output(ByVal strMessage As String, ByVal ParamArray args() As String)
        Output(strMessage, True, args)
    End Sub

    Public Shared Sub Output(ByVal strMessage As String, ByVal WriteTime As Boolean, ByVal ParamArray args() As String)
        Output(strMessage, WriteTime, False, args)
    End Sub

    ''' <summary>
    ''' Output to console and file
    ''' </summary>
    Public Shared Sub Output(ByVal strMessage As String, ByVal WriteTime As Boolean, ByVal IsException As Boolean, ByVal ParamArray args() As String)

        Dim strText As String
        Dim strFile As String = ConfigurationManager.AppSettings("logtofile")
        Static intFileCheck As Integer

        If args.Length > 0 Then
            strText = String.Format(strMessage, args)
        Else
            strText = strMessage
        End If

        If WriteTime Then
            strText = String.Format("{0} {1}", Now.ToString("HH:mm:ss"), strText)
        End If

        If Environment.UserInteractive Then
            If IsException Then
                Console.ForegroundColor = ConsoleColor.Red
            End If

            Console.WriteLine(strText)

            If IsException Then
                Console.ResetColor()
            End If

        End If

        If strFile <> "" Then
            Try
                'Check if the file exist and create versions if it becomes to big. Only check every 20 time
                'to avoid checking file props for every line written.
                If intFileCheck > 20 Then
                    If File.Exists(strFile) Then
                        If My.Computer.FileSystem.GetFileInfo(strFile).Length > 50000 Then
                            'Rename the file to fileyyyymmddhhmm.ext
                            File.Move(strFile, Path.Combine(Path.GetDirectoryName(strFile), String.Format("{0}{1}{2}", Path.GetFileNameWithoutExtension(strFile), Now.ToString("yyyyMMddHHmm"), Path.GetExtension(strFile))))
                        End If
                    End If
                    intFileCheck = 0
                End If

                File.AppendAllText(ConfigurationManager.AppSettings("logtofile"), strText & vbCrLf)

            Catch ex As Exception
                'Do nothing
            Finally
                intFileCheck += 1
            End Try

        End If

    End Sub

End Class
